home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 001 / pibt40s3.arc / PIBMDOS.MOD < prev    next >
Encoding:
Text File  |  1986-12-27  |  21.1 KB  |  441 lines

  1. (*--------------------------------------------------------------------------*)
  2. (*             PIBMDOS.PAS --- Multitasker interface routines               *)
  3. (*--------------------------------------------------------------------------*)
  4. (*                                                                          *)
  5. (*  Author:  Philip R. Burns                                                *)
  6. (*                                                                          *)
  7. (*  Date:    Version 1.0: January, 1986.   DoubleDos support.               *)
  8. (*           Version 2.0: April, 1986.     Add DesqView support.            *)
  9. (*           Version 3.0: July, 1986.      Add TopView/Windows support.     *)
  10. (*           Version 3.1: September, 1986. Update for TaskView support.     *)
  11. (*           Version 3.2: December, 1986.  Distinguish TaskView/DesqView.   *)
  12. (*                                                                          *)
  13. (*  Systems: MS DOS or PC DOS with DoubleDos/DesqView/TopView/Windows       *)
  14. (*           installed.                                                     *)
  15. (*                                                                          *)
  16. (*  History: These routines provide a simple interface for PibTerm          *)
  17. (*           with SoftLogic's DoubleDos multitasking executive,             *)
  18. (*           Quarterdeck's DesqView multitasker, IBM's TopView,             *)
  19. (*           MicroSoft's Windows, and Sunny Hill's TaskView.                *)
  20. (*           (Windows is handled as a Topview-emulating product.  This is   *)
  21. (*           also true for TaskView and DesqView, but those programs do     *)
  22. (*           not require the explicit screen updates TopView requires.      *)
  23. (*                                                                          *)
  24. (*           If you have another multitasker, you should be able to         *)
  25. (*           replace these routines fairly easily with similar-acting       *)
  26. (*           ones for your multitasker.  Use the global types defined       *)
  27. (*           for MultiTasker and MultiTaskerType.                           *)
  28. (*                                                                          *)
  29. (*           Note also that the routine Get_Screen_Address in Pibscren.pas  *)
  30. (*           needs to know about multitaskers.                              *)
  31. (*                                                                          *)
  32. (*           With DoubleDos, it is necessary to reobtain the display buffer *)
  33. (*           address every time the screen memory is written to.  With      *)
  34. (*           DesqView, this is unnecessary.  With TopView and Windows,      *)
  35. (*           it is necessary to inform them that the screen has changed.    *)
  36. (*           TaskView works like DesqView.                                  *)
  37. (*                                                                          *)
  38. (*--------------------------------------------------------------------------*)
  39. (*                                                                          *)
  40. (*           Please leave messages on Gene Plantz's BBS (312) 882 4145      *)
  41. (*           or Ron Fox's BBS (312) 940 6496.                               *)
  42. (*                                                                          *)
  43. (*--------------------------------------------------------------------------*)
  44.  
  45. (*--------------------------------------------------------------------------*)
  46. (*           IsTimeSharingActive --- Checks if multitasker is active        *)
  47. (*--------------------------------------------------------------------------*)
  48.  
  49. FUNCTION IsTimeSharingActive : BOOLEAN;
  50.  
  51. (*--------------------------------------------------------------------------*)
  52. (*                                                                          *)
  53. (*    Function: IsTimeSharingActive                                         *)
  54. (*                                                                          *)
  55. (*    Purpose:  Checks if multitasker is active                             *)
  56. (*                                                                          *)
  57. (*    Calling Sequence:                                                     *)
  58. (*                                                                          *)
  59. (*       Ts_On := IsTimeSharingActive : BOOLEAN;                            *)
  60. (*                                                                          *)
  61. (*          Ts_On --- TRUE if multitasker is active.                        *)
  62. (*                                                                          *)
  63. (*    Calls:  MsDos                                                         *)
  64. (*                                                                          *)
  65. (*--------------------------------------------------------------------------*)
  66.  
  67. VAR
  68.    Regs : RegPack;
  69.  
  70. (*--------------------------------------------------------------------------*)
  71.  
  72. FUNCTION Get_TopView_Screen_Address : BOOLEAN;
  73.  
  74. VAR
  75.    SegS : INTEGER;
  76.    SegO : INTEGER;
  77.  
  78. BEGIN (* Get_TopView_Screen_Address *)
  79.  
  80.    Regs.Di := 0;
  81.    Regs.Ax := $FE00;
  82.  
  83.    IF Color_Screen_Active THEN
  84.       Regs.Es := Color_Screen_Address
  85.    ELSE
  86.       Regs.Es := Mono_Screen_Address;
  87.  
  88.    SegO    := 0;
  89.    SegS    := Regs.Es;
  90.  
  91.    INTR( $10 , Regs );
  92.  
  93.    DesqView_Screen := PTR( Regs.Es , Regs.Di );
  94.  
  95.    Get_TopView_Screen_Address := ( ( Regs.Es <> SegS ) OR ( Regs.Di <> SegO ) );
  96.  
  97. END   (* Get_TopView_Screen_Address *);
  98.  
  99. (*--------------------------------------------------------------------------*)
  100.  
  101. BEGIN (* IsTimeSharingActive *)
  102.                                    (* Assume timesharing not active *)
  103.    IsTimeSharingActive := FALSE;
  104.    MultiTasker         := MultiTasker_None;
  105.  
  106.                                    (* Get initial screen address    *)
  107.    IF Color_Screen_Active THEN
  108.       DesqView_Screen := PTR( Color_Screen_Address , 0 )
  109.    ELSE
  110.       DesqView_Screen := PTR( Mono_Screen_Address  , 0 );
  111.  
  112.                                    (* If DDos is active, $E4 should *)
  113.                                    (* return a non-zero value in Al *)
  114.    Regs.Ax := $E400;
  115.    MsDos( Regs );
  116.  
  117.    IF ( Regs.Al <> 0 ) THEN
  118.       BEGIN
  119.          IsTimeSharingActive := TRUE;
  120.          MultiTasker         := DoubleDos;
  121.          EXIT;
  122.       END;
  123.                                    (* See if DesqView is active.        *)
  124.                                    (* We do a time/date call with       *)
  125.                                    (* DESQ as date.  If DesqView is     *)
  126.                                    (* active, this will be accepted.    *)
  127.                                    (* If not, it returns as invalid.    *)
  128.                                    (* While we're at it, get the        *)
  129.                                    (* display buffer address, which     *)
  130.                                    (* never changes.                    *)
  131.                                    (*                                   *)
  132.                                    (* NOTE:  Newer versions of TaskView *)
  133.                                    (*        also accept this DesqView  *)
  134.                                    (*        call, so we must check the *)
  135.                                    (*        TopView number to differ-  *)
  136.                                    (*        entiate them.              *)
  137.    Regs.Ax := $2B01;
  138.    Regs.Cx := $4445;  (*'DE'*)
  139.    Regs.Dx := $5351;  (*'SQ'*)
  140.    MsDos( Regs );
  141.  
  142.    IF ( Regs.Al <> $FF ) THEN
  143.       IF Get_TopView_Screen_Address THEN
  144.          BEGIN
  145.  
  146.             IsTimeSharingActive := TRUE;
  147.  
  148.                                    (* Distinguish TaskView from TopView *)
  149.             Regs.Ax := $1022;
  150.             Regs.Bx := 0;
  151.             INTR( $15 , Regs );
  152.  
  153.             IF ( Regs.Bx = 1 ) THEN
  154.                MultiTasker         := TaskView
  155.             ELSE
  156.                MultiTasker         := DesqView;
  157.  
  158.             EXIT;
  159.  
  160.          END;
  161.                                    (* Check for TaskView or TopView.  We do   *)
  162.                                    (* a request for a TopView version number. *)
  163.                                    (* If BX comes back $0001, this must be    *)
  164.                                    (* TaskView.  Anything non-zero indicates  *)
  165.                                    (* TopView or a compatible program.        *)
  166.                                    (* Note:  This catches older TaskView      *)
  167.                                    (*        versions which don't understand  *)
  168.                                    (*        the DesqView call.               *)
  169.    Regs.Ax := $1022;
  170.    Regs.Bx := 0;
  171.    INTR( $15 , Regs );
  172.  
  173.    IF ( Regs.Bx <> 0 ) THEN
  174.       BEGIN
  175.  
  176.          IF ( Regs.Bx = 1 ) THEN
  177.             MultiTasker         := TaskView
  178.          ELSE
  179.             MultiTasker         := TopView;
  180.  
  181.          IF ( NOT Get_TopView_Screen_Address ) THEN
  182.             MultiTasker := Multitasker_None
  183.          ELSE
  184.             IsTimeSharingActive := TRUE;
  185.  
  186.       END;
  187.  
  188. END   (* IsTimeSharingActive *);
  189.  
  190. (*--------------------------------------------------------------------------*)
  191. (*    TurnOnTimeSharing --- allow timesharing to proceed                    *)
  192. (*--------------------------------------------------------------------------*)
  193.  
  194. PROCEDURE TurnOnTimeSharing;
  195.  
  196. (*--------------------------------------------------------------------------*)
  197. (*                                                                          *)
  198. (*    Procedure:  TurnOnTimeSharing;                                        *)
  199. (*                                                                          *)
  200. (*    Purpose:    Activates timesharing                                     *)
  201. (*                                                                          *)
  202. (*    Calling Sequence:                                                     *)
  203. (*                                                                          *)
  204. (*       TurnOnTimeSharing;                                                 *)
  205. (*                                                                          *)
  206. (*    Calls:  MsDos                                                         *)
  207. (*                                                                          *)
  208. (*--------------------------------------------------------------------------*)
  209.  
  210. VAR
  211.    Regs : RegPack;
  212.  
  213. BEGIN (* TurnOnTimeSharing *)
  214.  
  215.    CASE MultiTasker OF
  216.                                    (* If DDos is active, $EB turns  *)
  217.                                    (* on timesharing                *)
  218.       DoubleDos:   BEGIN
  219.                       Regs.Ax := $EB00;
  220.                       MsDos( Regs );
  221.                    END;
  222.  
  223.                                    (* Int 15H for TopView family products *)
  224.       DesqView,
  225.       TopView,
  226.       MSWindows,
  227.       TaskView:    BEGIN
  228.                       Regs.Ax := $101C;
  229.                       INTR( $15 , Regs );
  230.                    END;
  231.  
  232.       ELSE;
  233.  
  234.    END (* CASE *);
  235.  
  236. END   (* TurnOnTimeSharing *);
  237.  
  238. (*--------------------------------------------------------------------------*)
  239. (*        TurnOffTimeSharing --- suspend timesharing under DoubleDos        *)
  240. (*--------------------------------------------------------------------------*)
  241.  
  242. PROCEDURE TurnOffTimeSharing;
  243.  
  244. (*--------------------------------------------------------------------------*)
  245. (*                                                                          *)
  246. (*    Procedure:  TurnOffTimeSharing;                                       *)
  247. (*                                                                          *)
  248. (*    Purpose:    Suspends timesharing                                      *)
  249. (*                                                                          *)
  250. (*    Calling Sequence:                                                     *)
  251. (*                                                                          *)
  252. (*       TurnOffTimeSharing;                                                *)
  253. (*                                                                          *)
  254. (*    Calls:  MsDos                                                         *)
  255. (*                                                                          *)
  256. (*--------------------------------------------------------------------------*)
  257.  
  258. VAR
  259.    Regs : RegPack;
  260.  
  261. BEGIN (* TurnOffTimeSharing *)
  262.  
  263.    CASE MultiTasker OF
  264.                                    (* If DDos is active, $EA suspends *)
  265.                                    (* timesharing                     *)
  266.       DoubleDos:   BEGIN
  267.                       Regs.Ax := $EA00;
  268.                       MsDos( Regs );
  269.                    END;
  270.                                    (* Int 15H for TopView family products *)
  271.       DesqView,
  272.       TopView,
  273.       MSWindows,
  274.       TaskView:    BEGIN
  275.                       Regs.Ax := $101B;
  276.                       INTR( $15 , Regs );
  277.                    END;
  278.  
  279.      ELSE;
  280.  
  281.    END (* CASE *);
  282.  
  283. END   (* TurnOffTimeSharing *);
  284.  
  285. (*--------------------------------------------------------------------------*)
  286. (*            GiveAwayTime --- gives away time slices to other task         *)
  287. (*--------------------------------------------------------------------------*)
  288.  
  289. PROCEDURE GiveAwayTime( NSlices : INTEGER );
  290.  
  291. (*--------------------------------------------------------------------------*)
  292. (*                                                                          *)
  293. (*    Procedure:  GiveAwayTime;                                             *)
  294. (*                                                                          *)
  295. (*    Purpose:    Gives away time slices to other tasks                     *)
  296. (*                                                                          *)
  297. (*    Calling Sequence:                                                     *)
  298. (*                                                                          *)
  299. (*       GiveAwayTime( NSlices :  INTEGER );                                *)
  300. (*                                                                          *)
  301. (*          NSlices --- # of slices (55 ms) to give away, if DoubleDos.     *)
  302. (*                                                                          *)
  303. (*    Calls:  MsDos                                                         *)
  304. (*                                                                          *)
  305. (*     Remarks:                                                             *)
  306. (*                                                                          *)
  307. (*        If a spooled file is being printed, then this routine causes a    *)
  308. (*        character to be sent to the printer, and the number of time       *)
  309. (*        slices to be donated to the other partition are halved.           *)
  310. (*        After printing the character (if any), the time slices are        *)
  311. (*        donated to the other multitasker partition(s), if nothing else    *)
  312. (*        is going on.                                                      *)
  313. (*                                                                          *)
  314. (*--------------------------------------------------------------------------*)
  315.  
  316. VAR
  317.    Regs : RegPack;
  318.  
  319. BEGIN (* GiveAwayTime *)
  320.  
  321.    IF Print_Spooling THEN
  322.       BEGIN
  323.          Print_Spooled_File;
  324.          NSlices := NSlices DIV 2;
  325.       END;
  326.  
  327.    IF ( TimeSharingActive AND ( NSlices > 0 ) ) THEN
  328.       CASE MultiTasker OF
  329.                                    (* Function EE gives time to other part. *)
  330.          DoubleDos:   BEGIN
  331.                          Regs.Ah := $EE;
  332.                          Regs.Al := NSlices;
  333.                          MsDos( Regs );
  334.                       END;
  335.  
  336.          DesqView,
  337.          TopView,
  338.          MSWindows,
  339.          TaskView:    BEGIN
  340.                          INLINE(
  341.                                  $B8/$00/$10 { MOV     AX,$1000 ;Give up time}
  342.                                  /$CD/$15    { INT     $15}
  343.                                );
  344.                       END;
  345.  
  346.          ELSE;
  347.  
  348.       END;
  349.  
  350. END   (* GiveAwayTime *);
  351.  
  352. (*--------------------------------------------------------------------------*)
  353. (*    Sync_Screen --- Synchronizes multitasker screen with hardware screen  *)
  354. (*--------------------------------------------------------------------------*)
  355.  
  356. PROCEDURE Sync_Screen( S_Pos: INTEGER; NChars : INTEGER );
  357.  
  358. (*--------------------------------------------------------------------------*)
  359. (*                                                                          *)
  360. (*    Procedure:  Sync_Screen;                                              *)
  361. (*                                                                          *)
  362. (*    Purpose:    Synchronizes multitasker and hardware screens             *)
  363. (*                                                                          *)
  364. (*    Calling Sequence:                                                     *)
  365. (*                                                                          *)
  366. (*       Sync_Screen( S_Pos : INTEGER; NChars: INTEGER );                   *)
  367. (*                                                                          *)
  368. (*    Calls:  INTR                                                          *)
  369. (*                                                                          *)
  370. (*    Remarks:                                                              *)
  371. (*                                                                          *)
  372. (*       This facility is required by the TopView-family products.          *)
  373. (*                                                                          *)
  374. (*--------------------------------------------------------------------------*)
  375.  
  376. BEGIN (* Sync_Screen *)
  377.  
  378.    IF ( MultiTasker IN [TopView,MSWindows] ) THEN
  379.       BEGIN
  380.  
  381. INLINE(
  382.   $55                      {         PUSH    BP                      ;Save BP in case of clobber}
  383.   /$C4/$3E/>DESQVIEW_SCREEN{         LES     DI,[>DesqView_Screen]   ;Pick up screen address}
  384.   /$8B/$8E/>NCHARS         {         MOV     CX,[BP+>NChars]         ;Get update length in bytes}
  385.   /$D1/$E9                 {         SHR     CX,1                    ;Update length in words}
  386.   /$8B/$86/>S_POS          {         MOV     AX,[BP+>S_Pos]          ;Get offset of area to update}
  387.   /$01/$F8                 {         ADD     AX,DI                   ;Add to offset of screen memory}
  388.   /$89/$C7                 {         MOV     DI,AX                   ;Starting address of update}
  389.   /$B4/$FF                 {         MOV     AH,$FF                  ;TopView synchronize screen}
  390.   /$CD/$10                 {         INT     $10                     ;Video interrupt}
  391.   /$5D                     {         POP     BP                      ;Restore BP}
  392. );
  393.  
  394.       END;
  395.  
  396. END   (* Sync_Screen *);
  397.  
  398. (*--------------------------------------------------------------------------*)
  399. (* Sync_Entire_Screen --- Synchronizes multitasker screen with hardware     *)
  400. (*--------------------------------------------------------------------------*)
  401.  
  402. PROCEDURE Sync_Entire_Screen;
  403.  
  404. (*--------------------------------------------------------------------------*)
  405. (*                                                                          *)
  406. (*    Procedure:  Sync_Entire_Screen;                                       *)
  407. (*                                                                          *)
  408. (*    Purpose:    Synchronizes multitasker and hardware screens             *)
  409. (*                                                                          *)
  410. (*    Calling Sequence:                                                     *)
  411. (*                                                                          *)
  412. (*       Sync_Entire_Screen;                                                *)
  413. (*                                                                          *)
  414. (*    Calls:  INTR                                                          *)
  415. (*                                                                          *)
  416. (*    Remarks:                                                              *)
  417. (*                                                                          *)
  418. (*       This facility is used by the TopView-family products when the      *)
  419. (*       entire screen has been updated.                                    *)
  420. (*                                                                          *)
  421. (*--------------------------------------------------------------------------*)
  422.  
  423. BEGIN (* Sync_Entire_Screen *)
  424.  
  425.    IF ( MultiTasker IN [TopView,MSWindows] ) THEN
  426.       BEGIN
  427.  
  428.       INLINE(
  429.   $55                       { PUSH    BP                    ;Save BP in case of clobber}
  430.   /$C4/$3E/>DESQVIEW_SCREEN { LES     DI,[>DesqView_Screen] ;Pick up screen address}
  431.   /$8B/$0E/>SCREEN_LENGTH   { MOV     CX,[>Screen_Length]   ;Get update length in bytes}
  432.   /$D1/$E9                  { SHR     CX,1                  ;Update length in words}
  433.   /$B4/$FF                  { MOV     AH,$FF                ;TopView synchronize screen}
  434.   /$CD/$10                  { INT     $10                   ;Video interrupt}
  435.   /$5D                      { POP     BP                    ;Restore BP}
  436.             );
  437.  
  438.       END;
  439.  
  440. END   (* Sync_Entire_Screen *);
  441.